package com.cardcaptorsakura.service.memory;

import com.cardcaptorsakura.model.entity.UserPreference;
import com.cardcaptorsakura.repository.UserPreferenceRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户偏好管理服务
 * 提供用户个性化设置的管理功能
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserPreferenceService {

    private final UserPreferenceRepository userPreferenceRepository;

    /**
     * 获取用户偏好
     */
    public Optional<UserPreference> getUserPreference(String userId) {
        try {
            Optional<UserPreference> preference = userPreferenceRepository.findByUserId(userId);
            if (preference.isPresent()) {
                log.debug("Found preference for user: {}", userId);
            } else {
                log.debug("No preference found for user: {}", userId);
            }
            return preference;
        } catch (Exception e) {
            log.error("Error getting user preference for user: {}", userId, e);
            return Optional.empty();
        }
    }

    /**
     * 创建或更新用户偏好
     */
    @Transactional
    public UserPreference saveUserPreference(UserPreference preference) {
        try {
            // 检查是否已存在
            Optional<UserPreference> existing = userPreferenceRepository.findByUserId(preference.getUserId());
            
            if (existing.isPresent()) {
                // 更新现有偏好
                UserPreference existingPreference = existing.get();
                updatePreferenceFields(existingPreference, preference);
                existingPreference.setUpdatedAt(LocalDateTime.now());
                
                UserPreference saved = userPreferenceRepository.save(existingPreference);
                log.info("Updated user preference for user: {}", preference.getUserId());
                return saved;
            } else {
                // 创建新偏好
                preference.setCreatedAt(LocalDateTime.now());
                preference.setUpdatedAt(LocalDateTime.now());
                
                UserPreference saved = userPreferenceRepository.save(preference);
                log.info("Created user preference for user: {}", preference.getUserId());
                return saved;
            }
        } catch (Exception e) {
            log.error("Error saving user preference for user: {}", preference.getUserId(), e);
            throw new RuntimeException("Failed to save user preference", e);
        }
    }

    /**
     * 更新语言偏好
     */
    @Transactional
    public UserPreference updateLanguagePreference(String userId, UserPreference.LanguagePreference languagePreference) {
        try {
            UserPreference preference = getOrCreateUserPreference(userId);
            preference.setLanguagePreference(languagePreference);
            preference.setUpdatedAt(LocalDateTime.now());
            
            UserPreference saved = userPreferenceRepository.save(preference);
            log.info("Updated language preference for user: {}, language: {}", userId, languagePreference.getPrimaryLanguage());
            return saved;
        } catch (Exception e) {
            log.error("Error updating language preference for user: {}", userId, e);
            throw new RuntimeException("Failed to update language preference", e);
        }
    }

    /**
     * 更新人格偏好
     */
    @Transactional
    public UserPreference updatePersonaPreference(String userId, UserPreference.PersonaPreference personaPreference) {
        try {
            UserPreference preference = getOrCreateUserPreference(userId);
            preference.setPersonaPreference(personaPreference);
            preference.setUpdatedAt(LocalDateTime.now());
            
            UserPreference saved = userPreferenceRepository.save(preference);
            log.info("Updated persona preference for user: {}, default persona: {}", userId, personaPreference.getDefaultPersonaId());
            return saved;
        } catch (Exception e) {
            log.error("Error updating persona preference for user: {}", userId, e);
            throw new RuntimeException("Failed to update persona preference", e);
        }
    }

    /**
     * 更新通知偏好
     */
    @Transactional
    public UserPreference updateNotificationPreference(String userId, UserPreference.NotificationPreference notificationPreference) {
        try {
            UserPreference preference = getOrCreateUserPreference(userId);
            preference.setNotificationPreference(notificationPreference);
            preference.setUpdatedAt(LocalDateTime.now());
            
            UserPreference saved = userPreferenceRepository.save(preference);
            log.info("Updated notification preference for user: {}", userId);
            return saved;
        } catch (Exception e) {
            log.error("Error updating notification preference for user: {}", userId, e);
            throw new RuntimeException("Failed to update notification preference", e);
        }
    }

    /**
     * 更新隐私偏好
     */
    @Transactional
    public UserPreference updatePrivacyPreference(String userId, UserPreference.PrivacyPreference privacyPreference) {
        try {
            UserPreference preference = getOrCreateUserPreference(userId);
            preference.setPrivacyPreference(privacyPreference);
            preference.setUpdatedAt(LocalDateTime.now());
            
            UserPreference saved = userPreferenceRepository.save(preference);
            log.info("Updated privacy preference for user: {}", userId);
            return saved;
        } catch (Exception e) {
            log.error("Error updating privacy preference for user: {}", userId, e);
            throw new RuntimeException("Failed to update privacy preference", e);
        }
    }

    /**
     * 更新界面偏好
     */
    @Transactional
    public UserPreference updateInterfacePreference(String userId, UserPreference.InterfacePreference interfacePreference) {
        try {
            UserPreference preference = getOrCreateUserPreference(userId);
            preference.setInterfacePreference(interfacePreference);
            preference.setUpdatedAt(LocalDateTime.now());
            
            UserPreference saved = userPreferenceRepository.save(preference);
            log.info("Updated interface preference for user: {}, theme: {}", userId, interfacePreference.getTheme());
            return saved;
        } catch (Exception e) {
            log.error("Error updating interface preference for user: {}", userId, e);
            throw new RuntimeException("Failed to update interface preference", e);
        }
    }

    /**
     * 更新交互偏好
     */
    @Transactional
    public UserPreference updateInteractionPreference(String userId, UserPreference.InteractionPreference interactionPreference) {
        try {
            UserPreference preference = getOrCreateUserPreference(userId);
            preference.setInteractionPreference(interactionPreference);
            preference.setUpdatedAt(LocalDateTime.now());
            
            UserPreference saved = userPreferenceRepository.save(preference);
            log.info("Updated interaction preference for user: {}", userId);
            return saved;
        } catch (Exception e) {
            log.error("Error updating interaction preference for user: {}", userId, e);
            throw new RuntimeException("Failed to update interaction preference", e);
        }
    }

    /**
     * 删除用户偏好
     */
    @Transactional
    public boolean deleteUserPreference(String userId) {
        try {
            Optional<UserPreference> preference = userPreferenceRepository.findByUserId(userId);
            if (preference.isPresent()) {
                userPreferenceRepository.delete(preference.get());
                log.info("Deleted user preference for user: {}", userId);
                return true;
            } else {
                log.warn("No preference found to delete for user: {}", userId);
                return false;
            }
        } catch (Exception e) {
            log.error("Error deleting user preference for user: {}", userId, e);
            return false;
        }
    }

    /**
     * 获取用户的语言偏好
     */
    public String getUserLanguage(String userId) {
        try {
            Optional<UserPreference> preference = getUserPreference(userId);
            if (preference.isPresent() && preference.get().getLanguagePreference() != null) {
                return preference.get().getLanguagePreference().getPrimaryLanguage();
            }
            return "zh-CN"; // 默认中文
        } catch (Exception e) {
            log.error("Error getting user language for user: {}", userId, e);
            return "zh-CN";
        }
    }

    /**
     * 获取用户的默认人格
     */
    public String getUserDefaultPersona(String userId) {
        try {
            Optional<UserPreference> preference = getUserPreference(userId);
            if (preference.isPresent() && preference.get().getPersonaPreference() != null) {
                return preference.get().getPersonaPreference().getDefaultPersonaId();
            }
            return null;
        } catch (Exception e) {
            log.error("Error getting user default persona for user: {}", userId, e);
            return null;
        }
    }

    /**
     * 检查用户是否启用了某个功能
     */
    public boolean isFeatureEnabled(String userId, String featureName) {
        try {
            Optional<UserPreference> preference = getUserPreference(userId);
            if (preference.isPresent() && preference.get().getInteractionPreference() != null) {
                Map<String, Boolean> features = preference.get().getInteractionPreference().getEnabledFeatures();
                return features != null && features.getOrDefault(featureName, true);
            }
            return true; // 默认启用
        } catch (Exception e) {
            log.error("Error checking feature enabled for user: {}, feature: {}", userId, featureName, e);
            return true;
        }
    }

    /**
     * 获取用户的主题偏好
     */
    public String getUserTheme(String userId) {
        try {
            Optional<UserPreference> preference = getUserPreference(userId);
            if (preference.isPresent() && preference.get().getInterfacePreference() != null) {
                return preference.get().getInterfacePreference().getTheme();
            }
            return "light"; // 默认浅色主题
        } catch (Exception e) {
            log.error("Error getting user theme for user: {}", userId, e);
            return "light";
        }
    }

    /**
     * 批量获取用户偏好
     */
    public List<UserPreference> getUserPreferences(List<String> userIds) {
        try {
            List<UserPreference> preferences = userPreferenceRepository.findByUserIdIn(userIds);
            log.debug("Found {} preferences for {} users", preferences.size(), userIds.size());
            return preferences;
        } catch (Exception e) {
            log.error("Error getting user preferences for users: {}", userIds, e);
            return Collections.emptyList();
        }
    }

    /**
     * 获取按语言分组的用户统计
     */
    public Map<String, Long> getUserLanguageStatistics() {
        try {
            List<UserPreference> allPreferences = userPreferenceRepository.findAll();
            
            Map<String, Long> statistics = allPreferences.stream()
                .filter(pref -> pref.getLanguagePreference() != null)
                .collect(Collectors.groupingBy(
                    pref -> pref.getLanguagePreference().getPrimaryLanguage(),
                    Collectors.counting()
                ));
            
            log.debug("Generated language statistics for {} users", allPreferences.size());
            return statistics;
        } catch (Exception e) {
            log.error("Error generating user language statistics", e);
            return Collections.emptyMap();
        }
    }

    /**
     * 获取按主题分组的用户统计
     */
    public Map<String, Long> getUserThemeStatistics() {
        try {
            List<UserPreference> allPreferences = userPreferenceRepository.findAll();
            
            Map<String, Long> statistics = allPreferences.stream()
                .filter(pref -> pref.getInterfacePreference() != null)
                .collect(Collectors.groupingBy(
                    pref -> pref.getInterfacePreference().getTheme(),
                    Collectors.counting()
                ));
            
            log.debug("Generated theme statistics for {} users", allPreferences.size());
            return statistics;
        } catch (Exception e) {
            log.error("Error generating user theme statistics", e);
            return Collections.emptyMap();
        }
    }

    /**
     * 重置用户偏好为默认值
     */
    @Transactional
    public UserPreference resetUserPreference(String userId) {
        try {
            UserPreference defaultPreference = createDefaultUserPreference(userId);
            UserPreference saved = userPreferenceRepository.save(defaultPreference);
            log.info("Reset user preference to default for user: {}", userId);
            return saved;
        } catch (Exception e) {
            log.error("Error resetting user preference for user: {}", userId, e);
            throw new RuntimeException("Failed to reset user preference", e);
        }
    }

    /**
     * 导出用户偏好
     */
    public Map<String, Object> exportUserPreference(String userId) {
        try {
            Optional<UserPreference> preference = getUserPreference(userId);
            if (preference.isPresent()) {
                Map<String, Object> export = new HashMap<>();
                UserPreference pref = preference.get();
                
                export.put("userId", pref.getUserId());
                export.put("languagePreference", pref.getLanguagePreference());
                export.put("personaPreference", pref.getPersonaPreference());
                export.put("notificationPreference", pref.getNotificationPreference());
                export.put("privacyPreference", pref.getPrivacyPreference());
                export.put("interfacePreference", pref.getInterfacePreference());
                export.put("interactionPreference", pref.getInteractionPreference());
                export.put("createdAt", pref.getCreatedAt());
                export.put("updatedAt", pref.getUpdatedAt());
                
                log.info("Exported user preference for user: {}", userId);
                return export;
            } else {
                log.warn("No preference found to export for user: {}", userId);
                return Collections.emptyMap();
            }
        } catch (Exception e) {
            log.error("Error exporting user preference for user: {}", userId, e);
            return Collections.emptyMap();
        }
    }

    /**
     * 获取或创建用户偏好
     */
    private UserPreference getOrCreateUserPreference(String userId) {
        Optional<UserPreference> existing = getUserPreference(userId);
        if (existing.isPresent()) {
            return existing.get();
        } else {
            return createDefaultUserPreference(userId);
        }
    }

    /**
     * 创建默认用户偏好
     */
    private UserPreference createDefaultUserPreference(String userId) {
        UserPreference preference = new UserPreference();
        preference.setUserId(userId);
        
        // 设置默认语言偏好
        UserPreference.LanguagePreference languagePreference = new UserPreference.LanguagePreference();
        languagePreference.setPrimaryLanguage("zh-CN");
        languagePreference.setSecondaryLanguages(Arrays.asList("en-US"));
        languagePreference.setAutoDetect(true);
        preference.setLanguagePreference(languagePreference);
        
        // 设置默认人格偏好
        UserPreference.PersonaPreference personaPreference = new UserPreference.PersonaPreference();
        personaPreference.setDefaultPersonaId("sakura");
        personaPreference.setFavoritePersonas(Arrays.asList("sakura"));
        personaPreference.setAutoSwitchEnabled(false);
        preference.setPersonaPreference(personaPreference);
        
        // 设置默认通知偏好
        UserPreference.NotificationPreference notificationPreference = new UserPreference.NotificationPreference();
        notificationPreference.setEmailEnabled(true);
        notificationPreference.setPushEnabled(true);
        notificationPreference.setSmsEnabled(false);
        notificationPreference.setQuietHours(Arrays.asList("22:00-08:00"));
        preference.setNotificationPreference(notificationPreference);
        
        // 设置默认隐私偏好
        UserPreference.PrivacyPreference privacyPreference = new UserPreference.PrivacyPreference();
        privacyPreference.setDataCollection(true);
        privacyPreference.setPersonalization(true);
        privacyPreference.setAnalytics(true);
        privacyPreference.setThirdPartySharing(false);
        preference.setPrivacyPreference(privacyPreference);
        
        // 设置默认界面偏好
        UserPreference.InterfacePreference interfacePreference = new UserPreference.InterfacePreference();
        interfacePreference.setTheme("light");
        interfacePreference.setFontSize("medium");
        interfacePreference.setAnimationEnabled(true);
        interfacePreference.setCompactMode(false);
        preference.setInterfacePreference(interfacePreference);
        
        // 设置默认交互偏好
        UserPreference.InteractionPreference interactionPreference = new UserPreference.InteractionPreference();
        interactionPreference.setVoiceEnabled(true);
        interactionPreference.setAutoPlay(false);
        interactionPreference.setTypingSpeed("normal");
        Map<String, Boolean> features = new HashMap<>();
        features.put("multiModal", true);
        features.put("memory", true);
        features.put("emotion", true);
        interactionPreference.setEnabledFeatures(features);
        preference.setInteractionPreference(interactionPreference);
        
        return preference;
    }

    /**
     * 更新偏好字段
     */
    private void updatePreferenceFields(UserPreference existing, UserPreference updated) {
        if (updated.getLanguagePreference() != null) {
            existing.setLanguagePreference(updated.getLanguagePreference());
        }
        if (updated.getPersonaPreference() != null) {
            existing.setPersonaPreference(updated.getPersonaPreference());
        }
        if (updated.getNotificationPreference() != null) {
            existing.setNotificationPreference(updated.getNotificationPreference());
        }
        if (updated.getPrivacyPreference() != null) {
            existing.setPrivacyPreference(updated.getPrivacyPreference());
        }
        if (updated.getInterfacePreference() != null) {
            existing.setInterfacePreference(updated.getInterfacePreference());
        }
        if (updated.getInteractionPreference() != null) {
            existing.setInteractionPreference(updated.getInteractionPreference());
        }
    }
}